(function (window) {
   //Ajax构造函数
   function Ajax(options) {
      return new init(options)
   }
   let init = function (options = {}) {
      let {
         type = 'GET',
         url,
         data = null,
         dataType = 'json',
         async = true,
         cache = true,
         success,
         error

      } = options;

      // 把配置项挂载到实例上
      for (let key in options) {
         this[key] = options[key]
      }
      // 实例发送
      this.sendAjax()
   }

   // 原型重定向
   Ajax.prototype = {
      constructor: Ajax,
      init: init,
      // Ajax原型上的sendAjax方法，this Ajax原型可以调用。 this.sendAajx()
      sendAjax() {
         // data默认值null
         let { type, url, async, data, cache, error, dataType, success } = this
         url = this.handleDate(type, data, url)//get加参数
         console.log(url)
         url = this.handleCache(type, url, cache)//get加时间戳
         console.log(url)
         console.log(this.data)
         let xhr = new XMLHttpRequest()
         xhr.open(type, url, async)
         this.handleHeahder(type, xhr)
         // 注意这里用箭头函数，否则里面用到的this通通是xhr,而不是ajax实例对象
         xhr.onreadystatechange = () => {
            if (!/^(2|3)\d{2}$/.test(xhr.status)) {
               error && error(xhr.statusText, xhr)
               return
            }
            if (xhr.readyState == 4) {

               //   dataType 从服务器那边返回的数据处理。dataType 
               // xhr.responseText 字符串
               let data = this.handleDateType(dataType, xhr)
               success(data, xhr)
            }

         }
         xhr.send(this.data)
      },
      handleHeahder(type, xhr) {
         if (/^POST$/i.test(type)) {
            xhr.setRequestHeader('content-type', "application/x-www-form-urlencoded")
         }
      },
      handleDateType(dataType, xhr) {
         dataType = dataType.toUpperCase()
         let result = xhr.responseText//默认是纯文本字符串
         return dataType == 'JSON' ? JSON.parse(result) : (dataType == 'XML' ? xhr.responseXML : result)
      },
      handleCache(type, url, cache) {
         // 处理get请求并且cacheshi false拼接随机数
         if (/^GET$/i.test(type) && cache === false) {
            console.log(url)
            console.log(url + `${this.check(url)}_=${new Date().getTime()}`)
            return url + `${this.check(url)}_=${new Date().getTime()}`

         }

         // 否则原样返回
         return url
      },
      check(url) {
         return url.includes('?') ? "&" : "?"
      },
      handleDate(type, data, url) {
         if (!data) return data
         let str = ''
         if (typeof data === 'object') {
            // 如果是object对象转为form-urlencoded格式 字符串string格式 a=b&c=d s
            for (let key in data) {
               // 空对象压根不会循环
               if (!data.hasOwnProperty(key)) return
               str += `${key}=${data[key]}&`
            }
            str = str.slice(0, -1)

         }
         if (/^(GET|HEAD|DELETE|TRACE|OPTIONS)$/i.test(type)) {
            this.data = null
            return url + this.check(url) + str
         }
         // post请求 post请求参数数据也是string.
         this.data = str
         return url
      }
   }
   init.prototype = Ajax.prototype
   window.ajax = Ajax
})(window)
